package com.wbp.cms.core.exception;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Service;

import com.wbp.cms.client.result.Result;

@Aspect
@Service
public class ExceptionHandlerAdvice {
  /**
   * The Constant logger.
   */
  private static final Logger logger = Logger.getLogger(ExceptionHandlerAdvice.class);
  private static final Long MAX_TIME = 100L;

  // @Around("execution(* org.cgi.cmsadmin.core.service..*.*(..)) || execution(* com.taobao.fed.service.mtop..*.*(..)) || execution(* com.taobao.fed.service.*.*(..))")
  @Around("execution(* com.wbp.cms.core.service..*.*(..)) || execution(* com.wbp.cms.core.user.service..*.*(..))  "
      + "|| execution(* com.wbp.cms.core.product.service..*.*(..)) || execution(* com.wbp.cms.core.project.service..*.*(..))")
  public Object aroundException(ProceedingJoinPoint joinPoint) throws Throwable {

    long beginTime = System.currentTimeMillis();
    try {
      return joinPoint.proceed(joinPoint.getArgs());
    } catch (Throwable e) {
      if (e instanceof IllegalArgumentException) {
        logger.error(ErrorType.ERR_VALIDATE.getMessage(), e);
        return Result.buildError(ErrorType.ERR_VALIDATE.getCode(), ErrorType.ERR_VALIDATE.getMessage());
      } else if (e instanceof ServiceException) {
        logger.error(ErrorType.ERR_BUSINESS.getMessage(), e);
        return Result.buildError(ErrorType.ERR_BUSINESS.getCode(),
            ErrorType.ERR_BUSINESS.getMessage());
      } else if (e instanceof SystemException) {
        logger.error(ErrorType.ERR_SYSTEM.getMessage(), e);
        return Result.buildError(ErrorType.ERR_SYSTEM.getCode(), ErrorType.ERR_SYSTEM.getMessage());
      } else if (e instanceof NullPointerException) {
        logger.error(ErrorType.ERR_SYSTEM.getMessage(), e);
        return Result.buildError(ErrorType.ERR_SYSTEM.getCode(), ErrorType.ERR_SYSTEM.getMessage());
      } else if (e instanceof CheckException) {
        logger.error(ErrorType.ERR_SYSTEM.getMessage(), e);
        return Result.buildError(ErrorType.ERR_SYSTEM.getCode(), ErrorType.ERR_SYSTEM.getMessage());
      } else {
        logger.error(ErrorType.ERR_UNKNOW.getMessage(), e);
        return Result.buildError(ErrorType.ERR_SYSTEM.getCode(), ErrorType.ERR_SYSTEM.getMessage());
      }
    } finally {
      // 记录调用大于100耗秒时间的类和方法，便于性能问题排查追踪
      long methodCostTime = System.currentTimeMillis() - beginTime;
      if (methodCostTime > MAX_TIME) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        logger.info("ExceptionAdvice,className:" + className + ";methodName:" + methodName
            + ";proceed time:" + methodCostTime);
      }
    }
  }
}
